Skip to content

Un-strip ui-text-android and ui-unit-android Compose bindings#1440

Merged
jonathanpeppers merged 3 commits into
mainfrom
copilot/un-strip-ui-text-android-ui-unit-android
Jun 5, 2026
Merged

Un-strip ui-text-android and ui-unit-android Compose bindings#1440
jonathanpeppers merged 3 commits into
mainfrom
copilot/un-strip-ui-text-android-ui-unit-android

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 4, 2026

Mirrors #1438 (which un-stripped ui-graphics-android) for the remaining Compose styling packages. ui-text-android and ui-unit-android previously shipped with <remove-node path="/api/package" /> and exported zero public types, forcing managed callers to hand-roll JNI lookups for FontWeight.Bold, Dp.Hairline, TextUnit.Unspecified, etc.

Metadata transforms

  • ui-text-android/Transforms/Metadata.xml — drop the package strip; add UI-cased managedName for every androidx.compose.ui.text.* package. Binding fixes: drop Comparable on FontWeight; drop Collection/List/CharSequence/Appendable on LocaleList/FontListFontFamily/AnnotatedString/AnnotatedString.Builder; rename the colliding append(String) overload; remove two members leaking the package-private PlatformLocaleDelegate and an unreferenced kotlinx.coroutines.CoroutineDispatcher.
  • ui-unit-android/Transforms/Metadata.xml — drop the strip; add UI-cased managedName; drop Comparable on Dp; rename inline-class operator/extension overloads that lower to identical primitive signatures (Div2/Constrain2/Minus2/Plus2/IntRect2/Lerp2/IsSpecified2/IsUnspecified2/TakeOrElse2).

Inline value-class types still surface as raw primitives at JNI (e.g. Dpfloat), consistent with the #1438 lowering policy; their companions and constants now bind.

Packaging / surface

  • AndroidXProject.cshtml — add Xamarin.AndroidX.Compose.UI.Text(.Android) and …UI.Unit(.Android) to ComposePackagesWithBindings (suppresses the "C# bindings are not provided" note).
  • published-namespaces.txt — add the 13 newly-exposed namespaces.
  • PublicAPI.Unshipped.txt — regenerated for both packages.
  • config.json — bump nugetVersion 1.11.21.11.2.1 for ui-text, ui-text-android, ui-unit, ui-unit-android.

This exposes real C# classes such as AndroidX.Compose.UI.Text.Font.FontWeight, …Text.Style.TextDecoration, …Text.TextStyle, …Unit.Dp.Companion, and …Unit.TextUnit.Companion.

foundation-layout-android collisions

Once Dp becomes resolvable, foundation-layout-android surfaces new Dp-based inline-class method collisions (CS0111) — anticipated in the issue's foundation note. These are now fixed:

  • foundation-layout-android/Transforms/Metadata.xml — add managedName renames for the mangled inline value-class overloads that lower to the same primitive signature as their un-mangled siblings: FlexConfigScope.basis-0680j_4Basis2; GridConfigurationScope.column-0680j_4/column-XZblgosColumn2/Column3 and row-0680j_4/row-XZblgosRow2/Row3; plus the matching ResolvedFlexItemInfo.basis-0680j_4Basis2 on the public implementing class. GridConfigurationScopeImpl is package-private, so it isn't bound and needs no transform. This mirrors the inline-class rename approach in ui-unit-android.

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Copilot AI changed the title [WIP] Un-strip ui-text-android and ui-unit-android Un-strip ui-text-android and ui-unit-android Compose bindings Jun 4, 2026
Copilot AI requested a review from jonathanpeppers June 4, 2026 22:28
@jonathanpeppers jonathanpeppers marked this pull request as ready for review June 4, 2026 23:38
Copilot AI review requested due to automatic review settings June 4, 2026 23:38
@jonathanpeppers
Copy link
Copy Markdown
Member

@copilot build errors:

D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Complications.Data.IComplicationText.cs(424,19): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\androidx.wear.watchface.watchface-complications-data.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Complications.Data.IComplicationText.cs(383,24): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\androidx.wear.watchface.watchface-complications-data.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Complications.Data.IComplicationText.cs(402,12): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\androidx.wear.watchface.watchface-complications-data.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Complications.Data.IComplicationText.cs(467,25): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\androidx.wear.watchface.watchface-complications-data.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Complications.Data.IComplicationText.cs(466,24): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\androidx.wear.watchface.watchface-complications-data.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\com.google.android.material.material\obj\Release\net10.0-android36.0\generated\src\Google.Android.Material.Carousel.FullScreenCarouselStrategy.cs(96,80): warning CS0672: Member 'FullScreenCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)' overrides obsolete member 'CarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. Add the Obsolete attribute to 'FullScreenCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. [D:\a\_work\1\s\generated\com.google.android.material.material\com.google.android.material.material.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\com.google.android.material.material\obj\Release\net10.0-android36.0\generated\src\Google.Android.Material.Carousel.HeroCarouselStrategy.cs(96,80): warning CS0672: Member 'HeroCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)' overrides obsolete member 'CarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. Add the Obsolete attribute to 'HeroCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. [D:\a\_work\1\s\generated\com.google.android.material.material\com.google.android.material.material.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\com.google.android.material.material\obj\Release\net10.0-android36.0\generated\src\Google.Android.Material.Carousel.MultiBrowseCarouselStrategy.cs(68,80): warning CS0672: Member 'MultiBrowseCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)' overrides obsolete member 'CarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. Add the Obsolete attribute to 'MultiBrowseCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. [D:\a\_work\1\s\generated\com.google.android.material.material\com.google.android.material.material.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\com.google.android.material.material\obj\Release\net10.0-android36.0\generated\src\Google.Android.Material.Carousel.UncontainedCarouselStrategy.cs(68,80): warning CS0672: Member 'UncontainedCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)' overrides obsolete member 'CarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. Add the Obsolete attribute to 'UncontainedCarouselStrategy.OnFirstChildMeasuredWithMargins(ICarousel, View)'. [D:\a\_work\1\s\generated\com.google.android.material.material\com.google.android.material.material.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\com.google.android.material.material\obj\Release\net10.0-android36.0\generated\src\Google.Android.Material.Internal.IStaticLayoutBuilderConfigurer.cs(63,14): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'StaticLayout.Builder' is only supported on: 'android' 23.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\com.google.android.material.material\com.google.android.material.material.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\source\com.google.android.gms\play-services-iid\Additions\Additions.cs(15,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. [D:\a\_work\1\s\generated\com.google.android.gms.play-services-iid\com.google.android.gms.play-services-iid.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\source\com.google.android.gms\play-services-iid\Additions\Additions.cs(28,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. [D:\a\_work\1\s\generated\com.google.android.gms.play-services-iid\com.google.android.gms.play-services-iid.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.IWatchFaceInstanceServiceStub.cs(56,88): warning CS0436: The type 'WatchFaceControlService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs' conflicts with the imported type 'WatchFaceControlService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs(243,79): warning CS0436: The type 'EditorService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs' conflicts with the imported type 'EditorService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs(308,82): warning CS0436: The type 'EditorService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs' conflicts with the imported type 'EditorService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs(168,57): warning CS0436: The type 'EditorService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs' conflicts with the imported type 'EditorService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs(63,131): warning CS0436: The type 'WatchFaceControlService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs' conflicts with the imported type 'WatchFaceControlService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs(122,93): warning CS0436: The type 'WatchFaceControlService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs' conflicts with the imported type 'WatchFaceControlService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs(159,93): warning CS0436: The type 'WatchFaceControlService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs' conflicts with the imported type 'WatchFaceControlService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs(201,93): warning CS0436: The type 'WatchFaceControlService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs' conflicts with the imported type 'WatchFaceControlService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Control.WatchFaceControlService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs(183,120): warning CS0436: The type 'EditorService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs' conflicts with the imported type 'EditorService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs(175,88): warning CS0436: The type 'EditorService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs' conflicts with the imported type 'EditorService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs(88,93): warning CS0436: The type 'EditorService' in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs' conflicts with the imported type 'EditorService' in 'Xamarin.AndroidX.Wear.WatchFace.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Editor.EditorService.cs'. [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.ICanvasComplication.cs(197,25): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'ZonedDateTime' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.ICanvasComplication.cs(354,25): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'ZonedDateTime' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.ICanvasComplication.cs(438,25): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'ZonedDateTime' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.IWatchFaceHostApi.cs(643,17): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Duration' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface\androidx.wear.watchface.watchface.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Client.IHeadlessWatchFaceClient.cs(553,13): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\androidx.wear.watchface.watchface-client.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Client.IHeadlessWatchFaceClient.cs(688,19): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\androidx.wear.watchface.watchface-client.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Client.IHeadlessWatchFaceClient.cs(738,19): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\androidx.wear.watchface.watchface-client.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Client.IInteractiveWatchFaceClient.cs(1043,13): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\androidx.wear.watchface.watchface-client.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Client.IRemoteWatchFaceViewHost.cs(91,13): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'SurfaceControlViewHost.SurfacePackage' is only supported on: 'android' 30.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\androidx.wear.watchface.watchface-client.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Client.IRemoteWatchFaceViewHost.cs(113,19): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\androidx.wear.watchface.watchface-client.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Client.IInteractiveWatchFaceClient.cs(1288,19): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Instant' is only supported on: 'android' 26.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416) [D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-client\androidx.wear.watchface.watchface-client.csproj::TargetFramework=net10.0-android36.0]
D:\a\_work\1\s\generated\androidx.compose.foundation.foundation-layout-android\obj\Release\net9.0-android35.0\generated\src\AndroidX.Compose.Foundation.Layout.IFlexConfigScope.cs(53,8): error CS0111: Type 'IFlexConfigScope' already defines a member called 'Basis' with the same parameter types [D:\a\_work\1\s\generated\androidx.compose.foundation.foundation-layout-android\androidx.compose.foundation.foundation-layout-android.csproj::TargetFramework=net9.0-android35.0]

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the androidx.compose.ui binding customizations so the ui-text-android and ui-unit-android NuGets ship real C#-consumable APIs (instead of being fully stripped), aligning them with the prior ui-graphics-android un-stripping work.

Changes:

  • Stop stripping all packages in ui-text-android and ui-unit-android, and apply consistent AndroidX.Compose.UI.* managed namespace casing via managedName metadata.
  • Add targeted metadata fixes to unblock binding generation (remove problematic interface implementations, rename signature-colliding overloads, and remove members that reference unbound/internal types).
  • Update packaging surface area and versioning (AndroidXProject.cshtml, published-namespaces.txt, PublicAPI.Unshipped.txt, and config.json NuGet revision bumps).

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
source/AndroidXProject.cshtml Marks the Compose UI Text/Unit packages as “with bindings” to suppress the “no C# bindings” note.
source/androidx.compose.ui/ui-unit-android/Transforms/Metadata.xml Un-strips the unit Android artifact, enforces UI casing, and resolves binding collisions via metadata adjustments.
source/androidx.compose.ui/ui-unit-android/PublicAPI/PublicAPI.Unshipped.txt Regenerated API surface reflecting newly exposed unit bindings.
source/androidx.compose.ui/ui-text-android/Transforms/Metadata.xml Un-strips the text Android artifact, enforces UI casing, and removes/renames members to avoid generator/interface issues.
source/androidx.compose.ui/ui-text-android/PublicAPI/PublicAPI.Unshipped.txt Regenerated API surface reflecting newly exposed text bindings.
published-namespaces.txt Adds newly exposed AndroidX.Compose.UI.Text.* and AndroidX.Compose.UI.Unit.* namespaces.
config.json Bumps NuGet revision (1.11.21.11.2.1) for the affected Compose UI Text/Unit artifacts.

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jun 4, 2026

@copilot build errors:

D:\a\_work\1\s\generated\androidx.wear.watchface.watchface-complications-data\obj\Release\net10.0-android36.0\generated\src\AndroidX.Wear.WatchFace.Complic...

Fixed in 1659cd0's follow-up commit. The blocking CS0111 came from foundation-layout-android: now that Dp resolves, the Kotlin inline-class overloads FlexConfigScope.basis-0680j_4(Dp), GridConfigurationScope.column/row (-0680j_4 Dp + -XZblgos), and ResolvedFlexItemInfo.basis-0680j_4 all lower to the same primitive signature as their un-mangled (float) siblings. I added managedName renames (Basis2, Column2/Column3, Row2/Row3) in foundation-layout-android/Transforms/Metadata.xml, mirroring the inline-class rename approach already used in ui-unit-android. GridConfigurationScopeImpl is package-private so it isn't bound and needs no transform.

The remaining CA1416/CS0672/CS0436/CS4014 items in the log are pre-existing warnings in unrelated packages (wear watchface, material, play-services-iid) and are not introduced by this PR.

@jonathanpeppers jonathanpeppers merged commit d79e945 into main Jun 5, 2026
2 checks passed
@jonathanpeppers jonathanpeppers deleted the copilot/un-strip-ui-text-android-ui-unit-android branch June 5, 2026 15:24
jonathanpeppers added a commit to jonathanpeppers/compose-net that referenced this pull request Jun 6, 2026
Closes #58 (the bulk of it — see _Deferred_ at the bottom for the remainder).

## What ships

### New `Text` properties
`Color`, `FontStyle`, `FontFamily`, `Align`, `Overflow`, `SoftWrap`, `MaxLines`, `MinLines`.

```csharp
new Text("Italic serif red, centered")
{
    Color      = ColorKt.Color(0xC6, 0x28, 0x28, 0xFF),
    FontStyle  = FontStyle.Italic,
    FontFamily = FontFamily.Serif,
    Align      = TextAlign.Center,
    Modifier   = Modifier.Companion.FillMaxWidth(),
}

new Text("This long line clips with an ellipsis…")
{
    MaxLines = 1,
    Overflow = TextOverflow.Ellipsis,
    SoftWrap = false,
}
```

### New `TextField` / `OutlinedTextField` slots
`Enabled`, `ReadOnly`, `Label`, `Placeholder`, `LeadingIcon`, `TrailingIcon`, `Prefix`, `Suffix`, `SupportingText`, `IsError`, `SingleLine`, `MaxLines`, `MinLines`.

```csharp
new TextField(name)
{
    Label          = new Text("Your name"),
    Placeholder    = new Text("Type something…"),
    LeadingIcon    = new Text("👤"),
    TrailingIcon   = new Text("✎"),
    SupportingText = new Text("Powered by issue #58 slots"),
    SingleLine     = true,
}
```

## Generator changes

`ComposeBridgeGenerator` and `ComposeFacadeGenerator` now recognize **nullable primitives** (`bool?`, `int?`, `long?`, `float?`, `double?`). At the bridge level these lower to `(name ?? defaultLiteral)` so a `null` clears the corresponding `$default` bit and Kotlin's default runs; at the facade level they surface as nullable auto-properties — parity with existing nullable Compose value types like `Dp?` / `Sp?`. Three tests cover the new behaviour (one bridge, one facade, one mixed).

## New wrapper types

| Type | Lowering | Why |
|------|----------|-----|
| `FontStyle` | reference (slot `L`) | `@JvmInline value class` but Compose declares `fontStyle:` nullable, which boxes |
| `FontFamily` | reference (slot `L`) | regular Kotlin class, just not bound yet |
| `TextOverflow` | packed `int` (slot `I`) | `@JvmInline value class`, declared **non-nullable** in Compose |
| `TextAlign` | reference (slot `L`) — **breaking change**, was a value struct | same boxing reason as `FontStyle` |

`FontStyle` and `TextAlign` reach Compose's companion via the mangled inline-class accessors (`getCenter-e0LSkKk()I`, `getNormal-_-LCdwA()I`) and box through the synthesized `box-impl(I)L<Type>;` static. `FontFamily`'s companion getters return concrete subtypes (`SystemFontFamily` / `GenericFontFamily`) so each call uses its exact descriptor. All names verified against `ui-text-android` 1.11.2.1 bytecode.

## Sample

The Greeting tab in `MainActivity.cs` now demos the new styling — color + italic serif center-aligned text, monospace end-aligned text, ellipsis clipping with `MaxLines = 1`, two-line clamp with reserved height, plus a `TextField` and `OutlinedTextField` exercising the new slots.

## Verification

- `dotnet test src/ComposeNet.SourceGenerators.Tests` — **83/83 passing**
- `dotnet build src/ComposeNet.Compose` — clean (`PublicAPI.Unshipped.txt` updated)
- `dotnet build src/ComposeNet.Sample` — clean

## Deferred (blocked or out of scope)

- **`KeyboardOptions` / `KeyboardActions`** — `KeyboardOptions` ctor is stripped from the binding (inline-class params: `KeyboardType`, `ImeAction`, `KeyboardCapitalization`); needs a `[ComposeBridge(JvmName="<init>")]` follow-up.
- **`VisualTransformation`, `AnnotatedString`, `TextStyle`, `LinkAnnotation`** — all in `androidx.compose.ui.text.input` / `androidx.compose.ui.text`, still 0 exported types until the next Compose package release post [dotnet/android-libraries#1440](dotnet/android-libraries#1440) (merged but not yet shipped).
- **`BasicText` / `BasicTextField` / `LocalTextStyle` / `FocusRequester`** — separate facades; out of scope here.

## Breaking change

`TextAlign` is no longer a `record struct`. Callers that previously used the `Pack` static, `Equals`/`Deconstruct`, or accessed `Value` directly will need to migrate; the `TextAlign.Left/Right/Center/Justify/Start/End/Unspecified` accessors are unchanged in name and still typed `TextAlign`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Un-strip ui-text-android and ui-unit-android (mirror #1438)

3 participants